package com.example.wms;

import java.io.IOException;
import java.util.*;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.*;
import com.example.classes.DataBase;
import com.example.classes.Item;
import com.example.classes.Member;

// -- Alex: example for displaying images: http://www.mkyong.com/android/android-listview-example/

/**
 * Class represents the list which displays the items to the user
 * @author Andrew, Alex
 */
public class itemListViewActivity extends Activity implements AdapterView.OnItemSelectedListener
{
    private ListView listView;
    private DataBase d;
    private TextView titleText;
    private EditText editText, distanceText, latText, longText;
    private String[] listview_array;
    private String[] sorted_listview_array;
    private final ArrayList<String> array_sort= new ArrayList<String>();
    private Intent intent;
    private String loggedinUser;
    private Collection<Item> itemList = new ArrayList<Item>();
    private HashMap<Item,Member> solveAllMyProblems= new HashMap<Item,Member>();
    private HashMap<String,Item> itemMap=new HashMap<String, Item>();
    private Spinner catspin, timespin, statspin;
    private eCategory catfilter = eCategory.ALL;
    private eTime timefilter = eTime.ALL;
    private eStatus statfilter = eStatus.ALL;
    private Object[] result_items;
    private boolean found;

    private enum eCategory
    {
        ALL, HEIRLOOMS, KEEPSAKES, MISCELLANEOUS
    }

    private enum eTime
    {
        ALL, DAY, WEEK, MONTH
    }

    private enum eStatus
    {
        ALL, UNRESOLVED, RESOLVED
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.item_list);

        d = new DataBase(this);

        found = getIntent().getBooleanExtra("found",false);

        listview_array = populateList();
        sorted_listview_array = listview_array;
        listView = (ListView)findViewById(R.id.ListView01);
        editText = (EditText)findViewById(R.id.EditText01);

        latText = (EditText)findViewById(R.id.latT);
        longText = (EditText)findViewById(R.id.longT);
        distanceText = (EditText)findViewById(R.id.distT);
        titleText = (TextView)findViewById(R.id.title_main);

        if (found)
            titleText.setText("Found Item List");

        intent = new Intent(this, ItemHandler.class);

        loggedinUser = getIntent().getStringExtra("username");
        result_items = itemList.toArray();      //to pass item into ItemHandler for item selection

        catspin = (Spinner) findViewById(R.id.catSpinner);
        ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(this, R.array.catfilters, android.R.layout.simple_spinner_item);
        adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        catspin.setAdapter(adapter1);
        catspin.setOnItemSelectedListener(this);

        timespin = (Spinner) findViewById(R.id.timeSpinner);
        ArrayAdapter<CharSequence> adapter2 = ArrayAdapter.createFromResource(this, R.array.timefilters, android.R.layout.simple_spinner_item);
        adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        timespin.setAdapter(adapter2);
        timespin.setOnItemSelectedListener(this);

        statspin = (Spinner) findViewById(R.id.statusSpinner);
        ArrayAdapter<CharSequence> adapter3 = ArrayAdapter.createFromResource(this, R.array.statusfilters, android.R.layout.simple_spinner_item);
        adapter3.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        statspin.setAdapter(adapter3);
        statspin.setOnItemSelectedListener(this);

        listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listview_array));

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView parentView, View childView, int position, long id)
            {
                intent.putExtra("username", solveAllMyProblems.get(itemMap.get(sorted_listview_array[position])));
                intent.putExtra("itemname", itemMap.get(sorted_listview_array[position]));
                intent.putExtra("sameuser", (solveAllMyProblems.get(itemMap.get(sorted_listview_array[position])).getName().equals(loggedinUser)));
                Log.v("WMS-DEBUG", "ITEMVIEW: position = " + position + "    id = " + id);
                Log.v("WMS-DEBUG", "ITEMVIEW: array value at position: " + listview_array[position]);

                startActivityForResult(intent, 1);

                Log.v("WMS-DEBUG", "ITEMVIEW: Post-SAfR 1");
            }
        });

        editText.addTextChangedListener(new TextWatcher(){
            public void afterTextChanged(Editable s){
                updateList();
            }

            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            public void onTextChanged(CharSequence s, int start, int before, int count)
            {
                updateList();
            }
        });

        distanceText.addTextChangedListener(new TextWatcher(){
            public void afterTextChanged(Editable s){
                updateList();
            }

            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            public void onTextChanged(CharSequence s, int start, int before, int count)
            {
                updateList();
            }
        });

        latText.addTextChangedListener(new TextWatcher(){
            public void afterTextChanged(Editable s){
                updateList();
            }

            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            public void onTextChanged(CharSequence s, int start, int before, int count)
            {
                updateList();
            }
        });

        longText.addTextChangedListener(new TextWatcher(){
            public void afterTextChanged(Editable s){
                updateList();
            }

            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            public void onTextChanged(CharSequence s, int start, int before, int count)
            {
                updateList();
            }
        });
    }

    /**
     * Called if the "Find similar items" button is pressed in the item screen.
     * Takes the given data and puts it into the search filters.
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        Log.v("WMS-DEBUG", "ITEMVIEW: Post-SAfR 2");
        if (data.getBooleanExtra("changed",false))
        {
            Log.v("WMS-DEBUG", "ITEMVIEW: The list was changed; updating!");

            if (data.getBooleanExtra("itemType", true))
            {
                found = false;
                titleText.setText("Lost Item List");
            }
            else
            {
                found = true;
                titleText.setText("Found Item List");
            }

            listview_array = populateList();
            sorted_listview_array = listview_array;
            result_items = itemList.toArray();

            if (data.getBooleanExtra("search", false))
            {
                editText.setText(data.getStringExtra("itemName"));
                switch (data.getStringExtra("itemCat").charAt(0))
                {
                    case 'A': catspin.setSelection(0); break;
                    case 'H': catspin.setSelection(1); break;
                    case 'K': catspin.setSelection(2); break;
                    case 'M': catspin.setSelection(3);
                }
                latText.setText(String.valueOf(data.getDoubleExtra("itemLat", 0.0)));
                longText.setText(String.valueOf(data.getDoubleExtra("itemLong", 0.0)));

            }
            updateList();
        }
        else
            Log.v("WMS-DEBUG", "ITEMVIEW: All is the same.");
    }

    /**
     * Called when a Spinner is updated
     */
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
    {
        String cat = String.valueOf(catspin.getSelectedItem());
        switch (cat.charAt(0))
        {
            case 'A': catfilter = eCategory.ALL; break;
            case 'H': catfilter = eCategory.HEIRLOOMS; break;
            case 'K': catfilter = eCategory.KEEPSAKES; break;
            case 'M': catfilter = eCategory.MISCELLANEOUS;
        }

        String time = String.valueOf(timespin.getSelectedItem());
        switch (time.charAt(5))
        {
            case 'i': timefilter = eTime.ALL; break;
            case '2': timefilter = eTime.DAY; break;
            case 'w': timefilter = eTime.WEEK; break;
            case 'm': timefilter = eTime.MONTH;
        }

        String stat = String.valueOf(statspin.getSelectedItem());
        switch (stat.charAt(0))
        {
            case 'A': statfilter = eStatus.ALL; break;
            case 'R': statfilter = eStatus.RESOLVED; break;
            case 'U': statfilter = eStatus.UNRESOLVED; break;
        }

        //Log.v("WMS-DEBUG","ItemListView: " + cat);
        //Log.v("WMS-DEBUG","ItemListView: " + time);
        //Log.v("WMS-DEBUG","ItemListView: " + stat);

        updateList();
    }

    public void onNothingSelected(AdapterView<?> parent) {}

    /**
     * Updates which items are visible to the user in the list
     */
    private void updateList()
    {
        int txtLength = editText.getText().length();
        array_sort.clear();
        int ind = 0;

        for (String aListview_array : listview_array)
        {
            if (txtLength <= aListview_array.length())
            {
                if (aListview_array.toLowerCase().contains(editText.getText().toString().toLowerCase()))
                {
                    boolean validAdd = true;
                    Item curr = (Item)result_items[ind];
                    String strDist = distanceText.getText().toString();

                    String latStr = latText.getText().toString();
                    String longStr = longText.getText().toString();

                    if (!strDist.equals("") && !latStr.equals("") && !longStr.equals(""))
                    {
                        double dist;
                        double latCoord;
                        double longCoord;
                        try
                        {
                            dist = Double.parseDouble(strDist) * 1000;
                            latCoord = Double.parseDouble(latStr);
                            longCoord = Double.parseDouble(longStr);

                            Location ItemLoc = curr.getLocation();

                            Location myLoc = new Location("Dummy");
                            myLoc.setLatitude(latCoord);
                            myLoc.setLongitude(longCoord);

                            if (ItemLoc.distanceTo(myLoc) > dist)
                                validAdd = false;
                        } catch (Exception e)
                        {
                            Log.v("WMS-DEBUG", "Error: " + e.toString());
                        }
                    }

                    switch (catfilter)
                    {
                        case HEIRLOOMS:
                            if (!curr.getCategory().equals("Heirloom"))
                                validAdd = false;
                            break;
                        case KEEPSAKES:
                            if (!curr.getCategory().equals("Keepsake"))
                                validAdd = false;
                            break;
                        case MISCELLANEOUS:
                            if (!curr.getCategory().equals("Misc"))
                                validAdd = false;
                            break;
                    }
                    if (validAdd)
                    {
                        Calendar cal = GregorianCalendar.getInstance();
                        cal.add(Calendar.DAY_OF_YEAR, -1);
                        Date day = cal.getTime();

                        //Log.v("WMS-DEBUG","Item: " + curr.getDate().toString());
                        //Log.v("WMS-DEBUG","Day: " + day.toString());

                        cal = GregorianCalendar.getInstance();
                        cal.add(Calendar.DAY_OF_YEAR, -7);
                        Date week = cal.getTime();
                        //Log.v("WMS-DEBUG","Week: " + week.toString());

                        cal = GregorianCalendar.getInstance();
                        cal.add(Calendar.DAY_OF_YEAR, -31);
                        Date month = cal.getTime();

                        //Log.v("WMS-DEBUG","Month: " + month.toString());
                        Date itemDate = curr.getDate();
                        //Log.v("WMS-DEBUG","after: " + itemDate.after(day));
                       // Log.v("WMS-DEBUG","timefilter!");
                        switch (timefilter)
                        {
                            case DAY:
                                if (!itemDate.after(day))
                                    validAdd = false;
                                break;
                            case WEEK:
                                if (!itemDate.after(week))
                                    validAdd = false;
                                break;
                            case MONTH:
                                if (!itemDate.after(month))
                                    validAdd = false;
                                break;
                        }
                    }
                    if (validAdd)
                    {
                        //Log.v("WMS-DEBUG","statfilter!");
                        switch (statfilter)
                        {
                            case UNRESOLVED:
                                if (curr.isResolve())
                                    validAdd = false;
                                break;
                            case RESOLVED:
                                if (!curr.isResolve())
                                    validAdd = false;
                                break;
                        }
                    }
                    if (validAdd)
                        array_sort.add(aListview_array);
                }
            }
            ind++;
        }
        sorted_listview_array = new String[array_sort.size()];
        int i = 0;
        for (Object o : array_sort)
            sorted_listview_array[i++] = (String)o;
        ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(itemListViewActivity.this, android.R.layout.simple_expandable_list_item_1, array_sort);
        listView.setAdapter(listAdapter);
    }

    /**
     * Populates the ListView with all of the Items in the database.
     */
    private String[] populateList()
    {
        d.open();
        ArrayList<String> stringItems = new ArrayList<String>();
        Collection<Member> users = d.getAllUsers();
        d.close();
        solveAllMyProblems = new HashMap<Item, Member>();
        itemList = new ArrayList<Item>();
        itemMap = new HashMap<String, Item>();
        for (Member u: users)  {
            for(Item f : u.getItems())
            {
                if(f.isState() == found)
                {
                    solveAllMyProblems.put(f,u);
                    itemList.add(f);
                    itemMap.put(f.getName(),f);
                }
            }
        }
        for (Item e:itemList)
            stringItems.add(e.toString());
       // Log.v("WMS-DEBUG","finalItems: " + stringItems.length);
        String[] finalItems = new String[stringItems.size()];
        int i = 0;
        for (String str: stringItems)
            finalItems[i++] = str;
        Log.v("WMS-DEBUG","finalItems: " + finalItems.length);
        return finalItems;
    }

    /**
     * Called when the "Back" button is pressed. Goes back to the home screen.
     * @param v  the content view
     */
    public void goBack(View v)
    {
        finish();
    }
}